<?php

namespace App\Lib\WeApp\Api;

use App\Lib\WeApp\Support\Encryptor;
use App\Lib\WeApp\Support\Message;
use App\Lib\WeApp\Support\Traits\DecryptXmlMessageTrait;
use App\Lib\WeApp\Support\Traits\InteractWithHandlersTrait;
use App\Lib\WeApp\Support\Traits\RespondXmlMessageTrait;
use Illuminate\Http\Response;
use Psr\Http\Message\ResponseInterface;
use Closure;

class MessageEvent extends BaseApi
{
    use InteractWithHandlersTrait;
    use DecryptXmlMessageTrait;
    use RespondXmlMessageTrait;

    protected ?Encryptor $encryptor = null;
    protected $aes_key;
    protected $token;

    public function __construct($appid,$secret, $token = '', $aes_key = '') {
        parent::__construct($appid,$secret, 'mini');
        $this->token = $token;
        $this->aes_key = $aes_key;
        $this->encryptor = new Encryptor($appid, $token, $aes_key);
    }

    // 下面是公众号消息处理
    public function response($request){
        // 公众号后台配置时，起验证作用
        if ((bool) ($str = $request->input('echostr') ?? '')) {
            return new Response($str, 200, []);
        }
        $message = Message::createFromRequest($request);
        $query = $request->all();
        if ($this->encryptor && ! empty($query['msg_signature'])) {
            $this->prepend($this->decryptRequestMessage($query));
        }

        $response = $this->handle(new Response('success',200, []), $message);
        if (! ($response instanceof ResponseInterface)) {
            try {
                $response = $this->transformToReply($response, $message, $this->encryptor);
            }catch (\Exception $e){
                return $response;
            }
        }
        return $response;
    }

    protected function decryptRequestMessage(array $query): Closure
    {
        return function (Message $message, Closure $next) use ($query): mixed {
            if (! $this->encryptor) {
                return null;
            }

            if(_empty_($query['msg_signature'] ?? '')){
                return $next($message);
            }

            $this->decryptMessage($message, $this->encryptor, $query['msg_signature'] ?? '', $query['timestamp'] ?? '', $query['nonce'] ?? '');

            return $next($message);
        };
    }
    /**
     */
    public function getDecryptedMessage($request)
    {
        $message = Message::createFromRequest($request);
        $query = $request->all();

        if (! $this->encryptor || empty($query['msg_signature'])) {
            return $message;
        }

        return $this->decryptMessage($message, $this->encryptor, $query['msg_signature'], $query['timestamp'] ?? '', $query['nonce'] ?? ''
        );
    }

}
